/*
 * @(#)Xfplot2DPanel.java        1.0 2000/05/09
 *
 * This file is part of Xfuzzy 3.0, a design environment for fuzzy logic
 * based systems.
 *
 * (c) 2000 IMSE-CNM. The authors may be contacted by the email address:
 *                    xfuzzy-team@imse.cnm.es
 *
 * Xfuzzy is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Xfuzzy is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

package xfuzzy.xfplot.view;

import javax.imageio.ImageIO;
import javax.swing.*;


import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;

/**
 * Clase que desarrolla el panel para la representaci�n gr�fica en 2
 * dimensiones
 * 
 * @author Francisco Jos� Moreno Velo
 *
 */
public class Xfplot2DPanel extends JPanel {
	
	//----------------------------------------------------------------------------//
	//                            CONSTANTES PRIVADAS                             //
	//----------------------------------------------------------------------------//

	/**
	 * C�digo asociado a la clase serializable
	 */
	private static final long serialVersionUID = 95505666603053L;
	
	/**
	 * Altura del panel
	 */
	private static final int HEIGHT = 500;
	
	/**
	 * Anchura del panel
	 */
	private static final int WIDTH = 700;
	
	//----------------------------------------------------------------------------//
	//                            MIEMBROS PRIVADOS                              //
	//----------------------------------------------------------------------------//

	/**
	 * Referencia al ap�gina principal de la aplicaci�n
	 */
	private Xfplot xfplot;
	
	//----------------------------------------------------------------------------//
	//                                CONSTRUCTOR                                 //
	//----------------------------------------------------------------------------//

	/**
	 * Constructor
	 */
	public Xfplot2DPanel(Xfplot xfplot) {
		super();
		this.xfplot = xfplot;
		setSize(new Dimension(WIDTH,HEIGHT));
		setPreferredSize(new Dimension(WIDTH,HEIGHT));
		setBackground(Color.white);
		setBorder(BorderFactory.createLoweredBevelBorder());
	}
	
 	//----------------------------------------------------------------------------//
	//                             M�TODOS P�BLICOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Pinta la representaci�n gr�fica. 
	 * Este m�todo sobreescribe el m�todo paint() de JPanel(). 
	 */
	public void paint(Graphics g) {
		super.paint(g);
		paintAxis(g);
		paintVariables(g);
		paintFunction(g);
	}
	
	/**
	 * Almacena la representaci�n gr�fica en un fichero externo
	 */
	public boolean saveImage(File file) {
		try {
			int width = getSize().width;
			int height = getSize().height;
			BufferedImage bi = (BufferedImage) createImage(width,height);
			Graphics2D g = (Graphics2D) bi.getGraphics();
			g.setColor(Color.white);
			g.fillRect(0, 0, width, height);
			g.setColor(Color.black);
			paintAxis(g);
			paintVariables(g);
			paintFunction(g);
			
			if(file.getName().endsWith(".jpg")) ImageIO.write(bi,"jpg",file);
			else ImageIO.write(bi,"png",file);
			return true;
		} catch (Exception ex) { return false; }
	}
	//----------------------------------------------------------------------------//
	//                             M�TODOS PRIVADOS                               //
	//----------------------------------------------------------------------------//
	
	/**
	 * Dibuja los ejes de la representaci�n gr�fica
	 */
	private void paintAxis(Graphics g) {
		int width = getSize().width;
		int height = getSize().height;
		int xmin = width/8;
		int xmax = width*7/8;
		int ymin = height*7/8;
		int ymax = height/8;
		g.drawLine(xmin, ymin, xmin, ymax);
		g.drawLine(xmin, ymin, xmax, ymin);
		for(int i=0; i<6; i++) {
			int y = ymin + (ymax - ymin)*i/5;
			g.drawLine(xmin-3, y, xmin, y);
		}
		for(int i=0; i<6; i++) {
			int x = xmin + (xmax - xmin)*i/5;
			g.drawLine(x, ymin+3, x, ymin);
		}
	}
	
	/**
	 * Dibuja los nombres de las variables a representar
	 */
	private void paintVariables(Graphics g) {
		int width = getSize().width;
		int height = getSize().height;
		int xx = width * 9 / 10;
		int xy = height * 9 / 10;
		int yx = width / 10;
		int yy = height / 10;
		g.drawString(xfplot.getXVariable().toString(), xx, xy);
		g.drawString(xfplot.getZVariable().toString(), yx, yy);
	}
	
	/**
	 * Dibuja la funci�n en tramos lineales
	 */
	private void paintFunction(Graphics g) {
		double function[] = xfplot.get2DFunction();
		if(function == null) return;
		int x0, y0, x1, y1;
		
		int width = getSize().width;
		int height = getSize().height;
		
		int xrange = width * 3 / 4;
		int yrange = height * 3 / 4;
		int xmin = width/8;
		int ymin = height*7/8;
		Color old = g.getColor();
		g.setColor(Color.red);
		
		x0 = xmin;
		y0 = ymin - (int) Math.round(function[0]*yrange);
		for(int i=1; i<function.length; i++) {
			x1 = xmin + i*xrange/(function.length-1);
			y1 = ymin - (int) Math.round(function[i]*yrange);
			g.drawLine(x0,y0,x1,y1);
			x0 = x1;
			y0 = y1;
		}
		g.setColor(old);
	}
}
